home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Nebula 2
/
Nebula Two.iso
/
SourceCode
/
Palettes
/
TablePrinter
/
DBTableViewPrinter.m
< prev
next >
Wrap
Text File
|
1995-06-12
|
25KB
|
839 lines
// DBTableViewPrinter -- An object for printing DBTableViews.
//
// By Eric T. Seymour, NeXT Computer, Inc.
//
// This object formats and prints DBTableViews. Basically, the drawself:
// method draws the table (in brute force fashion). It also contains methods
// for setting options.
//
// You may freely copy, distribute, and reuse the code in this example.
// NeXT disclaims any warranty of any kind, expressed or implied, as to its
// fitness for any particular use.
//
// This file looks best when using tabstops of 3.
#import <dbkit/dbkit.h>
#import <appkit/appkit.h>
#import "DBTableViewPrinter.h"
#import "TablePrintPanel.h"
#define CURRENT_CLASS_VERSION 1
@interface DBTableViewPrinter(Private)
- refreshLayout; // Page Layout stuff
@end
@implementation DBTableViewPrinter
+ initialize
{
// Set version for read/write backward compatibility
if ( self == [DBTableViewPrinter class] )
[DBTableViewPrinter setVersion:CURRENT_CLASS_VERSION];
return self;
}
- initFrame:(const NXRect *)frameRect
{
// initialize the frame
[super initFrame:frameRect];
[self setFlipped:YES];
// Initialize some flags and variables
tableView = nil;
rowHeight = 0.0;
pageNumSepChar = '-';
isPrinting = NO;
isPageNumbersEnabled = NO;
isRowNumbersEnabled = NO;
isSelectedRowsOnly = NO;
isForceDrawColor = NO;
startingPageNumber = 1;
startingRowNumber = 1;
isGridLinesOn = YES;
strcpy(rowNumberHeaderTitle,"#");
gridColor = NX_COLORBLACK;
backgroundColor = NX_COLORWHITE;
rowNumbersBackColor = NXConvertGrayToColor(0.17);
// Create Cell with which to draw titles
headerTextCell = [[TextFieldCell alloc] initTextCell:""];
[headerTextCell setFont:
[Font boldSystemFontOfSize:12.0 matrix:NX_FLIPPEDMATRIX]];
[headerTextCell setWrap:NO];
[headerTextCell setAlignment:NX_CENTERED];
[headerTextCell setTextColor:NX_COLORWHITE];
[headerTextCell setTextGray:NX_WHITE];
[headerTextCell setBackgroundGray:0.17];
[headerTextCell calcCellSize:&headerTextCellSize];
// Create Cell with which to draw row number headers
rowNumberHeaderCell = [[TextFieldCell alloc] initTextCell:""];
[rowNumberHeaderCell setFont:
[Font boldSystemFontOfSize:12.0 matrix:NX_FLIPPEDMATRIX]];
[rowNumberHeaderCell setWrap:NO];
[rowNumberHeaderCell setAlignment:NX_CENTERED];
[rowNumberHeaderCell setTextColor:NX_COLORWHITE];
[rowNumberHeaderCell setTextGray:NX_WHITE];
[rowNumberHeaderCell setBackgroundGray:0.17];
// Create Cell with which to draw row numbers
rowNumberCell = [[TextFieldCell alloc] initTextCell:""];
[rowNumberCell setFont:
[Font boldSystemFontOfSize:12.0 matrix:NX_FLIPPEDMATRIX]];
[rowNumberCell setWrap:NO];
[rowNumberCell setAlignment:NX_RIGHTALIGNED];
[rowNumberCell setTextColor:NX_COLORWHITE];
[rowNumberCell setTextGray:NX_WHITE];
[rowNumberCell setBackgroundGray:-1.0]; // Make background 100% Alpha
// Create Cell with which to draw page number
pageNumberCell = [[TextFieldCell alloc] initTextCell:""];
[pageNumberCell setWrap:NO];
[pageNumberCell setTextColor:NX_COLORBLACK];
[pageNumberCell setTextGray:NX_BLACK];
[pageNumberCell calcCellSize:&pageNumberCellSize];
[pageNumberCell setBackgroundGray:-1.0];
// set my page frame
if ( frameRect )
{
pageFrame.origin.x = frameRect->origin.x;
pageFrame.origin.y = frameRect->origin.y;
pageFrame.size.width = frameRect->size.width;
pageFrame.size.height = frameRect->size.height;
}
else
{
pageFrame.origin.x = pageFrame.origin.y = 0.0;
pageFrame.size.width = pageFrame.size.height = 20.0;
}
return self;
}
// Toggles and methods for color drawing
- setForceDrawColor:(BOOL)toggle
{
isForceDrawColor = toggle;
return self;
}
- (BOOL)isForceDrawColor{return isForceDrawColor;}
- (BOOL)shouldDrawColor
{
if ( isForceDrawColor ) return YES;
else return [super shouldDrawColor];
}
- free
{
// Free the Cells I was using
[headerTextCell free];
[rowNumberHeaderCell free];
[rowNumberCell free];
[pageNumberCell free];
return [super free];
}
- setPageNumbersEnabled:(BOOL)toggle
{
isPageNumbersEnabled = toggle;
if ( isPrinting ) [self refreshLayout];
return self;
}
- (BOOL)isPageNumbersEnabled{return isPageNumbersEnabled;}
- setStartingPageNumber:(int)num
{
startingPageNumber = num;
return self;
}
- (int)startingPageNumber{return startingPageNumber;}
- setPageNumberSeparator:(char)ch
{
if ( NXIsPrint(ch) ) pageNumSepChar = ch;
return self;
}
- (char)pageNumberSeparator{return pageNumSepChar;}
- setRowNumbersEnabled:(BOOL)toggle
{
isRowNumbersEnabled = toggle;
if ( isPrinting ) [self refreshLayout];
return self;
}
- (BOOL)isRowNumbersEnabled{return isRowNumbersEnabled;}
- setStartingRowNumber:(int)num
{
startingRowNumber = num;
if ( isPrinting ) [self refreshLayout];
return self;
}
- (int)startingRowNumber{return startingRowNumber;}
- setRowNumbersTitle:(const char *)title
{
if ( title == NULL ) return nil;
memset(rowNumberHeaderTitle,0,51);
strncpy(rowNumberHeaderTitle,title,50);
if ( isPrinting ) [self refreshLayout];
return self;
}
- (const char *)rowNumbersTitle{return rowNumberHeaderTitle;}
- setGridLinesOn:(BOOL)toggle
{
isGridLinesOn = toggle;
return self;
}
- (BOOL)isGridLinesOn{return isGridLinesOn;}
- setSelectedRowsOnly:(BOOL)toggle
{
isSelectedRowsOnly = toggle;
if ( isPrinting ) [self refreshLayout];
return self;
}
- (BOOL)isSelectedRowsOnly{return isSelectedRowsOnly;}
// Set Headers Bezeled Toggle
- setColumnHeadersBezeled:(BOOL)toggle
{
[headerTextCell setBezeled:toggle];
[rowNumberHeaderCell setBezeled:toggle];
[headerTextCell calcCellSize:&headerTextCellSize];
return self;
}
- (BOOL)isColumnHeadersBezeled{return [headerTextCell isBezeled];}
// Colors
- setColumnHeadersTextColor:(NXColor)color
{
float gray;
NXConvertColorToGray(color,&gray);
[headerTextCell setTextColor:color];
[headerTextCell setTextGray:gray];
[rowNumberHeaderCell setTextColor:color];
[rowNumberHeaderCell setTextGray:gray];
return self;
}
- (NXColor)columnHeadersTextColor{return [headerTextCell textColor];}
- setColumnHeadersBackColor:(NXColor)color
{
float gray;
NXConvertColorToGray(color,&gray);
[headerTextCell setBackgroundColor:color];
[headerTextCell setBackgroundGray:gray];
[rowNumberHeaderCell setBackgroundColor:color];
[rowNumberHeaderCell setBackgroundGray:gray];
return self;
}
- (NXColor)columnHeadersBackColor{return [headerTextCell backgroundColor];}
- setRowNumbersTextColor:(NXColor)color
{
float gray;
NXConvertColorToGray(color,&gray);
[rowNumberCell setTextColor:color];
[rowNumberCell setTextGray:gray];
return self;
}
- (NXColor)rowNumbersTextColor{return [rowNumberCell textColor];}
- setRowNumbersBackColor:(NXColor)color
{
rowNumbersBackColor = color;
return self;
}
- (NXColor)rowNumbersBackColor{return rowNumbersBackColor;}
- setGridLinesColor:(NXColor)color
{
gridColor = color;
return self;
}
- (NXColor)gridLinesColor{return gridColor;}
- setPageNumberColor:(NXColor)color
{
float gray;
NXConvertColorToGray(color,&gray);
[pageNumberCell setTextColor:color];
[pageNumberCell setTextGray:gray];
return self;
}
- (NXColor)pageNumberColor{return [pageNumberCell textColor];}
- setBackgroundColor:(NXColor)color
{
backgroundColor = color;
return self;
}
- (NXColor)backgroundColor{return backgroundColor;}
- printPSCode:sender
{
id rv;
// Print only if table has been set to a valid DBTableView or subclass
// thereof
if ( !tableView || ![tableView isKindOfClassNamed:"DBTableView"] )
return nil;
// set all instance variables before printing
[self refreshLayout];
// turn on printing flag and print
isPrinting = YES;
rv = [super printPSCode:sender];
// turn off printing flag and return
isPrinting = NO;
return rv;
}
// Setting/Get the current DBTableView
- setTableView:table
{
tableView = table;
return self;
}
- tableView{return tableView;}
- drawSelf:(const NXRect *)rects :(int)rectCount
{
id aVector;
int page,subPage,
i,j,
colStart,colEnd,colsThisPage;
unsigned int row,actualRow,actualPageRowStart,pageRowStart,
rowNumber,actualRowNumberStart;
double tmpDouble;
NXSize cellSize;
NXCoord theSize;
char pageNumberString[50];
float gray;
NXColor localBackgroundColor = backgroundColor,
localGridColor = gridColor,
localRowNumberBackColor = rowNumbersBackColor;
NXRect aRect;
int bezelDrawOffset = 0,
bezelForwardOffset = 0;
BOOL isBezeledHeaders = NO;
// don't waste time if this is not a call from printPSCode
if ( !isPrinting ) return [super drawSelf:rects :rectCount];
// set an offset for bezeled headers
if ( [headerTextCell isBezeled] )
{
bezelDrawOffset = 5; // offset to forward origin.y after header
bezelForwardOffset = 4; // offset to consider when advancing to next page
isBezeledHeaders = YES;
}
else
{
bezelDrawOffset = -1; // offset to forward origin.y after header
bezelForwardOffset = -2;// offset to consider when advancing to next page
isBezeledHeaders = NO;
}
// Clear to proper colors. If drawing in B&W, then convert the gray values
if ( ![self shouldDrawColor] )
{
NXConvertColorToGray(backgroundColor,&gray);
localBackgroundColor = NXConvertGrayToColor(gray);
NXConvertColorToGray(gridColor,&gray);
localGridColor = NXConvertGrayToColor(gray);
NXConvertColorToGray(rowNumbersBackColor,&gray);
localRowNumberBackColor = NXConvertGrayToColor(gray);
}
NXSetColor(localBackgroundColor);
NXRectFill(&pageFrame);
// Now go through and print each full tableview page
row = 0;
page = startingPageNumber;
theRect.origin.y = 0.0;
actualRow = 0;
rowNumber = startingRowNumber;
while ( actualRow < maxRows )
{
colStart = 0;
// determine how many cols can fit on this page
for ( colsThisPage = 0,tmpDouble = 0.0,i = colStart;i < maxColumns;i++ )
{
[headerTextCell setStringValue:[[columnList objectAt:i] title]];
[headerTextCell calcCellSize:&cellSize];
theSize = [(DBTableVector *)[columnList objectAt:i] size];
if ( theSize < cellSize.width ) theSize = cellSize.width;
tmpDouble += theSize;
if ( tmpDouble > rowNumberedWidth ) break;
else colsThisPage++;
}
if ( colsThisPage == 0 ) colsThisPage = 1;
colEnd = colsThisPage;
pageRowStart = row;
actualPageRowStart = actualRow;
actualRowNumberStart = rowNumber;
subPage = 1;
while ( colStart < maxColumns )
{
row = pageRowStart;
actualRow = actualPageRowStart;
rowNumber = actualRowNumberStart;
// Draw Page number if required
if ( isPageNumbersEnabled )
{
theRect.origin.y += pageNumberHeight;
if ( NXPointInRect(&theRect.origin,&rects[0]) )
{
if ( pagesPerRow > 1 )
sprintf(pageNumberString,"%d%c%d",
page,pageNumSepChar,subPage);
else sprintf(pageNumberString,"%d",page);
[pageNumberCell setStringValue:pageNumberString];
[pageNumberCell calcCellSize:&cellSize];
theRect.origin.x = pageFrame.size.width - cellSize.width;
theRect.size.width = cellSize.width;
theRect.size.height = pageNumberHeight;
[pageNumberCell drawSelf:&theRect inView:self];
}
}
// Initialize the first draw rect for the header row
theRect.origin.x = 0.0;
theRect.origin.y += headerTextCellSize.height;
theRect.size.height = headerTextCellSize.height;
// Put a header at the top of the page
if ( NXPointInRect(&theRect.origin,&rects[0]) )
{
// Put the Row Number Header if required
if ( isRowNumbersEnabled )
{
theRect.size.width = rowNumberHeaderCellSize.width;
[rowNumberHeaderCell drawSelf:&theRect inView:self];
// Draw border around row number header
if ( isGridLinesOn && !isBezeledHeaders )
{
// Set the color of the lines
NXSetColor(localGridColor);
// Draw Left, Top, and Right Borders
PSmoveto(theRect.origin.x,
theRect.origin.y + rowNumberHeaderCellSize.height);
PSlineto(theRect.origin.x,theRect.origin.y);
PSlineto(theRect.origin.x +
rowNumberHeaderCellSize.width - 1,
theRect.origin.y);
PSlineto(theRect.origin.x +
rowNumberHeaderCellSize.width - 1,
theRect.origin.y + rowNumberHeaderCellSize.height);
}
theRect.origin.x += rowNumberHeaderCellSize.width;
}
// Put the rest of the header
for ( i = colStart; i < colEnd; i++ )
{
aVector = [columnList objectAt:i];
[headerTextCell setStringValue:[aVector title]];
[headerTextCell calcCellSize:&cellSize];
theSize = [(DBTableVector *)aVector size];
if ( theSize < cellSize.width ) theSize = cellSize.width;
theRect.size.width = theSize;
[headerTextCell setAlignment:[aVector titleAlignment]];
[headerTextCell drawSelf:&theRect inView:self];
// Draw border around each header
if ( isGridLinesOn && !isBezeledHeaders )
{
// Set the color of the lines
NXSetColor(localGridColor);
// Draw Top and Right Borders
PSmoveto(theRect.origin.x,theRect.origin.y);
PSlineto(theRect.origin.x + theRect.size.width - 1,
theRect.origin.y);
PSlineto(theRect.origin.x + theRect.size.width - 1,
theRect.origin.y + theRect.size.height);
}
theRect.origin.x += theSize;
}
}
// Now print rows on this page until no more fit
theRect.size.height = rowHeight;
theRect.origin.y += bezelDrawOffset;
for ( i = 0; i < maxRowsPerPage && actualRow < maxRows; row++ )
{
// Skip if selection is on and this is not selected
if ( isSelectedRowsOnly && ![tableView isRowSelected:row] )
continue;
// Initialize the first draw rect for the current row
theRect.origin.x = 0.0;
theRect.origin.y += rowHeight;
// Now do each cell by having each formatter draw itself
if ( NXPointInRect(&theRect.origin,&rects[0]) )
{
// Draw a Row Number Cell if required
if ( isRowNumbersEnabled )
{
// Draw the background
NXSetColor(localRowNumberBackColor);
NXSetRect(&aRect,theRect.origin.x,theRect.origin.y + 1,
rowNumberHeaderCellSize.width - 1,rowHeight);
// If the first row, then narrow the gap above the first
// row number with row number background color
if ( actualRow == actualPageRowStart )
{
aRect.origin.y--;
aRect.size.height++;
if ( !isGridLinesOn )
{
aRect.origin.y--;
aRect.size.height++;
}
}
NXRectFill(&aRect);
// Draw the number using the cell
[rowNumberCell setIntValue:rowNumber];
NXSetRect(&aRect,theRect.origin.x,theRect.origin.y,
rowNumberHeaderCellSize.width,rowHeight);
[rowNumberCell drawSelf:&aRect inView:self];
// Draw draw lines around row numbers if required
if ( isGridLinesOn )
{
// Set the color of the lines
NXSetColor(localGridColor);
// Draw Left Border
PSmoveto(theRect.origin.x,theRect.origin.y);
PSlineto(theRect.origin.x,theRect.origin.y+rowHeight);
// Always draw bottom and right borders
PSlineto(theRect.origin.x +
rowNumberHeaderCellSize.width - 1,
theRect.origin.y + rowHeight);
PSlineto(theRect.origin.x +
rowNumberHeaderCellSize.width - 1,
theRect.origin.y);
// Only put top border on first rows
if ( actualRow == actualPageRowStart )
PSlineto(theRect.origin.x - 1,theRect.origin.y);
}
theRect.origin.x += rowNumberHeaderCellSize.width;
}
// Draw the rest of the cells
for ( j = colStart; j < colEnd; j++ )
{
[headerTextCell
setStringValue:[[columnList objectAt:j] title]];
[headerTextCell calcCellSize:&cellSize];
theSize = [(DBTableVector *)[columnList objectAt:j] size];
if ( theSize < cellSize.width ) theSize = cellSize.width;
theRect.size.width = theSize;
[[tableView formatterAt:row :j] beginBatching:nil];
theRect.origin.y++;
[[tableView formatterAt:row :j] drawFieldAt:row :j
inside:&theRect inView:self
withAttributes:[tableView rowAt:row]
:[tableView columnAt:j] usePositions:YES :NO];
theRect.origin.y--;
[[tableView formatterAt:row :j] endBatching];
// Draw the grid lines if required
if ( isGridLinesOn )
{
// Set the color of the lines
NXSetColor(localGridColor);
// Only put left borders on first columns and
// if row numbers are turned off
if ( j == colStart && !isRowNumbersEnabled )
{
PSmoveto(theRect.origin.x,theRect.origin.y);
PSlineto(theRect.origin.x,theRect.origin.y+rowHeight);
}
else
PSmoveto(theRect.origin.x - 1,
theRect.origin.y+rowHeight);
// Always draw bottom and right borders
PSlineto(theRect.origin.x + theRect.size.width - 1,
theRect.origin.y + rowHeight);
PSlineto(theRect.origin.x + theRect.size.width - 1,
theRect.origin.y);
// Only put top border on first rows
if ( actualRow == actualPageRowStart )
{
if ( j == colStart )
PSlineto(theRect.origin.x,theRect.origin.y);
else PSlineto(theRect.origin.x - 1,theRect.origin.y);
}
}
theRect.origin.x += theRect.size.width;
}
if ( isGridLinesOn || isRowNumbersEnabled ) PSstroke();
}
rowNumber++;
actualRow++;
i++;
}
theRect.origin.y--;
// advance the draw rect's origin to the next page
// The bezelForwardOffset is to compensate jumping bezelDrawOffset
// pixels after drawing the header
if ( i == maxRowsPerPage )
theRect.origin.y += pageAdvanceOffset - bezelForwardOffset;
else
theRect.origin.y += pageHeight -
((i * rowHeight) + headerTextCellSize.height +
pageNumberHeight + bezelForwardOffset);
colStart = colEnd;
// determine how many cols can fit on next page
for ( colsThisPage = 0,tmpDouble = 0.0,i = colStart;
i < maxColumns; i++ )
{
[headerTextCell setStringValue:[[columnList objectAt:i] title]];
[headerTextCell calcCellSize:&cellSize];
theSize = [(DBTableVector *)[columnList objectAt:i] size];
if ( theSize < cellSize.width ) theSize = cellSize.width;
tmpDouble += theSize;
if ( tmpDouble > rowNumberedWidth ) break;
else colsThisPage++;
}
if ( colsThisPage == 0 ) colsThisPage = 1;
colEnd += colsThisPage;
subPage++;
}
page++;
}
return self;
}
- read:(NXTypedStream*)stream
{
int version;
[super read:stream];
// Get the version
version = NXTypedStreamClassVersion(stream,"DBTableViewPrinter");
// Read all version 0 stuff first
NXReadTypes(stream,"cccccc@",&isPrinting,&isPageNumbersEnabled,
&isRowNumbersEnabled,&isSelectedRowsOnly,&isGridLinesOn,
&isForceDrawColor,&columnList);
headerTextCell = NXReadObject(stream);
pageNumberCell = NXReadObject(stream);
rowNumberHeaderCell = NXReadObject(stream);
rowNumberCell = NXReadObject(stream);
NXReadTypes(stream,"c[51c]",&pageNumSepChar,&rowNumberHeaderTitle);
NXReadTypes(stream,"{ffff}",&pageFrame);
NXReadTypes(stream,"{ffff}",&theRect);
NXReadTypes(stream,"fffff",&rowHeight,&pageHeight,
&pageAdvanceOffset,&pageNumberHeight,&rowNumberedWidth);
NXReadTypes(stream,"{ff}{ff}{ff}",
&headerTextCellSize,&pageNumberCellSize,&rowNumberHeaderCellSize);
NXReadTypes(stream,"iiiiii",
&maxColumns,&maxRows,&maxRowsPerPage,&pagesPerRow,
&startingPageNumber,&startingRowNumber);
gridColor = NXReadColor(stream);
backgroundColor = NXReadColor(stream);
NXReadTypes(stream,"@",&tableView);
// Read Version 1 stuff
if ( version > 0 ) rowNumbersBackColor = NXReadColor(stream);
return self;
}
- write:(NXTypedStream*)stream
{
[super write:stream];
// Write version 0 stuff first
NXWriteTypes(stream,"cccccc@",&isPrinting,&isPageNumbersEnabled,
&isRowNumbersEnabled,&isSelectedRowsOnly,&isGridLinesOn,
&isForceDrawColor,&columnList);
NXWriteObject(stream,headerTextCell);
NXWriteObject(stream,pageNumberCell);
NXWriteObject(stream,rowNumberHeaderCell);
NXWriteObject(stream,rowNumberCell);
NXWriteTypes(stream,"c[51c]",&pageNumSepChar,&rowNumberHeaderTitle);
NXWriteTypes(stream,"{ffff}",&pageFrame);
NXWriteTypes(stream,"{ffff}",&theRect);
NXWriteTypes(stream,"fffff",&rowHeight,&pageHeight,
&pageAdvanceOffset,&pageNumberHeight,&rowNumberedWidth);
NXWriteTypes(stream,"{ff}{ff}{ff}",
&headerTextCellSize,&pageNumberCellSize,&rowNumberHeaderCellSize);
NXWriteTypes(stream,"iiiiii",
&maxColumns,&maxRows,&maxRowsPerPage,&pagesPerRow,
&startingPageNumber,&startingRowNumber);
NXWriteColor(stream,gridColor);
NXWriteColor(stream,backgroundColor);
NXWriteTypes(stream,"@",&tableView);
// write version 1 stuff
NXWriteColor(stream,rowNumbersBackColor);
return self;
}
@end
@implementation DBTableViewPrinter(Private)
// refreshLayout gets the page size and determines all size parameters like
// the number of rows per page, the number of columns per page, etc.
- refreshLayout
{
int i,
bezelDrawOffset = 0,
maxPages;
NXRect visibleRect;
NXSize cellSize;
NXCoord theSize,
leftMargin,rightMargin,topMargin,bottomMargin;
const NXRect *paperRect;
double tmpDouble;
char title[51];
id thePrintPanel = nil;
// Get some formatter and size information from the tableView
columnList = [tableView columnList];
maxColumns = [columnList count];
if ( isSelectedRowsOnly ) maxRows = [tableView selectedRowCount];
else maxRows = [tableView rowCount];
if ( [tableView rowCount] > 0 ) rowHeight = [[tableView rowAt:0] size];
if ( rowHeight <= 0.0 ) rowHeight = 18;
// Lock the table's window and make sure everything has been displayed
// if everything has not been displayed, it will not get printed, so I
// have to "force a dislay" here, even if it is off screen.
[[tableView window] disableFlushWindow];
[[[tableView docView] superview] getDocVisibleRect:&visibleRect];
for ( i = 0; i < maxColumns; i++ )
[(DBTableView *)tableView scrollColumnToVisible:i];
[tableView scrollClip:[tableView docView] to:&visibleRect.origin];
[tableView reflectScroll:[[tableView docView] superview]];
[tableView layoutChanged:self];
[[tableView window] reenableFlushWindow];
// Get the width of a page
[[NXApp printInfo] getMarginLeft:&leftMargin right:&rightMargin
top:&topMargin bottom:&bottomMargin];
paperRect = [[NXApp printInfo] paperRect];
pageFrame.size.width =
(NXCoord)paperRect->size.width - (NXCoord)(rightMargin + leftMargin);
rowNumberedWidth = pageFrame.size.width;
// If row numbering is on, set the row header cell to the correct width
if ( isRowNumbersEnabled )
{
// Get the size of the number of digits in maxRow
[rowNumberHeaderCell setIntValue:(maxRows + startingRowNumber) * 10];
[rowNumberHeaderCell calcCellSize:&cellSize];
// Initialize the rowHeader sizes and values
[rowNumberHeaderCell setStringValue:rowNumberHeaderTitle];
[rowNumberHeaderCell calcCellSize:&rowNumberHeaderCellSize];
// Keep making the Row Header wider until it's wide enough
memset(title,0,51);
strncpy(title,rowNumberHeaderTitle,50);
while ( rowNumberHeaderCellSize.width < cellSize.width &&
strlen(title) < 45 )
{
sprintf(title," %s ",[rowNumberHeaderCell stringValue]);
[rowNumberHeaderCell setStringValue:title];
[rowNumberHeaderCell calcCellSize:&rowNumberHeaderCellSize];
}
rowNumberedWidth -= rowNumberHeaderCellSize.width;
}
// Get total pages to print a row
for ( pagesPerRow = 1, tmpDouble = 0.0, i = 0; i < maxColumns; i++ )
{
[headerTextCell setStringValue:[[columnList objectAt:i] title]];
[headerTextCell calcCellSize:&cellSize];
theSize = [(DBTableVector *)[columnList objectAt:i] size];
if ( theSize < cellSize.width ) theSize = cellSize.width;
tmpDouble += theSize;
if ( tmpDouble > rowNumberedWidth )
{
if ( i < (maxColumns - 1) && !(theSize > rowNumberedWidth &&
tmpDouble == theSize) ) i--;
pagesPerRow++;
tmpDouble = 0.0;
}
}
// Set the height of the page number cell if desired
if ( isPageNumbersEnabled ) pageNumberHeight = pageNumberCellSize.height;
else pageNumberHeight = 0.0;
// offset to forward origin.y after drawing each header
if ( [headerTextCell isBezeled] ) bezelDrawOffset = 5;
// Get the single page height and the whole rect needed to print this thing
pageHeight = paperRect->size.height - (topMargin + bottomMargin);
tmpDouble =
(double)((pageHeight - headerTextCellSize.height) -
(pageNumberHeight + bezelDrawOffset)) / (double)rowHeight;
maxRowsPerPage = (int)floor(tmpDouble) - 1;
tmpDouble = (double)maxRows / (double)maxRowsPerPage;
maxPages = (int)ceil(tmpDouble) * pagesPerRow;
if ( maxPages <= 0 ) maxPages = 1;
pageFrame.size.height = (NXCoord)maxPages * (NXCoord)pageHeight;
// Size the View in which to draw
[self sizeTo:pageFrame.size.width :pageFrame.size.height];
// Get the offset to add to advance to the next page
pageAdvanceOffset = pageHeight - ((maxRowsPerPage * rowHeight) +
headerTextCellSize.height + pageNumberHeight);
// Get my subclass of print panel and print with the proper pagesPerRow
thePrintPanel = [TablePrintPanel new];
if ( thePrintPanel &&
[thePrintPanel respondsTo:@selector(setPagesPerRow:)] )
[thePrintPanel setPagesPerRow:pagesPerRow];
return self;
}
@end